home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / tiff / tools / pal2rgb.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  7KB  |  251 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/pal2rgb.c,v 1.8 92/02/10 19:04:13 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include "tiffio.h"
  31.  
  32. typedef    unsigned char u_char;
  33. typedef    unsigned short u_short;
  34. typedef    unsigned long u_long;
  35.  
  36. #define    howmany(x, y)    (((x)+((y)-1))/(y))
  37. #define    streq(a,b)    (strcmp(a,b) == 0)
  38. #define    CopyField(tag, v) \
  39.     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
  40. #define    CopyField3(tag, v1, v2, v3) \
  41.     if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
  42.  
  43. static int
  44. checkcmap(n, r, g, b)
  45.     int n;
  46.     u_short *r, *g, *b;
  47. {
  48.     while (n-- > 0)
  49.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  50.         return (16);
  51.     fprintf(stderr, "Warning, assuming 8-bit colormap.\n");
  52.     return (8);
  53. }
  54.  
  55. main(argc, argv)
  56.     char *argv[];
  57. {
  58.     short bitspersample, samplesperpixel, shortv;
  59.     u_long imagewidth, imagelength;
  60.     short config = PLANARCONFIG_CONTIG;
  61.     u_short compression = -1;
  62.     long rowsperstrip = -1;
  63.     float floatv;
  64.     char *stringv;
  65.     u_long longv;
  66.     u_short *rmap, *gmap, *bmap;
  67.     u_long row;
  68.     short s;
  69.     int cmap = -1;
  70.     TIFF *in, *out;
  71.  
  72.     argc--, argv++;
  73.     if (argc < 2)
  74.         usage();
  75.     for (; argc > 2 && argv[0][0] == '-'; argc--, argv++) {
  76.         if (streq(argv[0], "-none")) {
  77.             compression = COMPRESSION_NONE;
  78.             continue;
  79.         }
  80.         if (streq(argv[0], "-packbits")) {
  81.             compression = COMPRESSION_PACKBITS;
  82.             continue;
  83.         }
  84.         if (streq(argv[0], "-lzw")) {
  85.             compression = COMPRESSION_LZW;
  86.             continue;
  87.         }
  88.         if (streq(argv[0], "-contig")) {
  89.             config = PLANARCONFIG_CONTIG;
  90.             continue;
  91.         }
  92.         if (streq(argv[0], "-separate")) {
  93.             config = PLANARCONFIG_SEPARATE;
  94.             continue;
  95.         }
  96.         if (streq(argv[0], "-8bit")) {
  97.             cmap = 8;
  98.             continue;
  99.         }
  100.         if (streq(argv[0], "-16bit")) {
  101.             cmap = 16;
  102.             continue;
  103.         }
  104.         if (streq(argv[0], "-rowsperstrip")) {
  105.             argc--, argv++;
  106.             rowsperstrip = atoi(argv[0]);
  107.             continue;
  108.         }
  109.         usage();
  110.     }
  111.     in = TIFFOpen(argv[0], "r");
  112.     if (in == NULL)
  113.         exit(-1);
  114.     if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) ||
  115.         shortv != PHOTOMETRIC_PALETTE) {
  116.         fprintf(stderr, "%s: Expecting a palette image.\n", argv[0]);
  117.         exit(-1);
  118.     }
  119.     if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
  120.         fprintf(stderr,
  121.             "%s: No colormap (not a valid palette image).\n",
  122.             argv[0]);
  123.         exit(-1);
  124.     }
  125.     out = TIFFOpen(argv[1], "w");
  126.     if (out == NULL)
  127.         exit(-2);
  128.     CopyField(TIFFTAG_SUBFILETYPE, longv);
  129.     CopyField(TIFFTAG_IMAGEWIDTH, imagewidth);
  130.     CopyField(TIFFTAG_IMAGELENGTH, imagelength);
  131.     CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
  132.     if (bitspersample != 8) {
  133.         fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
  134.             argv[0]);
  135.         exit(-1);
  136.     }
  137.     if (compression != (u_short)-1)
  138.         TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  139.     else
  140.         CopyField(TIFFTAG_COMPRESSION, compression);
  141.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  142.     CopyField(TIFFTAG_ORIENTATION, shortv);
  143.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
  144.     CopyField(TIFFTAG_PREDICTOR, shortv);
  145.     CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
  146.     CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
  147.     CopyField(TIFFTAG_XRESOLUTION, floatv);
  148.     CopyField(TIFFTAG_YRESOLUTION, floatv);
  149.     CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
  150.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
  151.     if (rowsperstrip <= 0)
  152.         rowsperstrip = (8*1024)/TIFFScanlineSize(out);
  153.     TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
  154.         rowsperstrip == 0 ? 1 : rowsperstrip);
  155.     CopyField(TIFFTAG_XPOSITION, floatv);
  156.     CopyField(TIFFTAG_YPOSITION, floatv);
  157.     CopyField(TIFFTAG_ARTIST, stringv);
  158.     CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv);
  159.     CopyField(TIFFTAG_MAKE, stringv);
  160.     CopyField(TIFFTAG_MODEL, stringv);
  161.     CopyField(TIFFTAG_SOFTWARE, stringv);
  162.     CopyField(TIFFTAG_DATETIME, stringv);
  163.     CopyField(TIFFTAG_HOSTCOMPUTER, stringv);
  164.     CopyField(TIFFTAG_PAGENAME, stringv);
  165.     CopyField(TIFFTAG_DOCUMENTNAME, stringv);
  166.     (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
  167.     if (cmap == -1)
  168.         cmap = checkcmap(1<<bitspersample, rmap, gmap, bmap);
  169.     if (cmap == 16) {
  170.         /*
  171.          * Convert 16-bit colormap to 8-bit.
  172.          */
  173.         int i;
  174.  
  175.         for (i = (1<<bitspersample)-1; i > 0; i--) {
  176. #define    CVT(x)        (((x) * 256) / ((1L<<16)-1))
  177.             rmap[i] = CVT(rmap[i]);
  178.             gmap[i] = CVT(gmap[i]);
  179.             bmap[i] = CVT(bmap[i]);
  180.         }
  181.     }
  182.     { u_char *ibuf, *obuf;
  183.       register u_char* pp;
  184.       register u_long x;
  185.       ibuf = (u_char*)malloc(TIFFScanlineSize(in));
  186.       obuf = (u_char*)malloc(TIFFScanlineSize(out));
  187.       switch (config) {
  188.       case PLANARCONFIG_CONTIG:
  189.         for (row = 0; row < imagelength; row++) {
  190.             if (!TIFFReadScanline(in, ibuf, row, 0))
  191.                 goto done;
  192.             pp = obuf;
  193.             for (x = 0; x < imagewidth; x++) {
  194.                 *pp++ = rmap[ibuf[x]];
  195.                 *pp++ = gmap[ibuf[x]];
  196.                 *pp++ = bmap[ibuf[x]];
  197.             }
  198.             if (!TIFFWriteScanline(out, obuf, row, 0))
  199.                 goto done;
  200.         }
  201.         break;
  202.       case PLANARCONFIG_SEPARATE:
  203.         for (row = 0; row < imagelength; row++) {
  204.             if (!TIFFReadScanline(in, ibuf, row, 0))
  205.                 goto done;
  206.             for (pp = obuf, x = 0; x < imagewidth; x++)
  207.                 *pp++ = rmap[ibuf[x]];
  208.             if (!TIFFWriteScanline(out, obuf, row, 0))
  209.                 goto done;
  210.             for (pp = obuf, x = 0; x < imagewidth; x++)
  211.                 *pp++ = gmap[ibuf[x]];
  212.             if (!TIFFWriteScanline(out, obuf, row, 0))
  213.                 goto done;
  214.             for (pp = obuf, x = 0; x < imagewidth; x++)
  215.                 *pp++ = bmap[ibuf[x]];
  216.             if (!TIFFWriteScanline(out, obuf, row, 0))
  217.                 goto done;
  218.         }
  219.         break;
  220.       }
  221.       free(ibuf);
  222.       free(obuf);
  223.     }
  224. done:
  225.     (void) TIFFClose(in);
  226.     (void) TIFFClose(out);
  227. }
  228.  
  229. usage()
  230. {
  231.     fprintf(stderr, "usage: pal2rgb [options] input output\n");
  232.     fprintf(stderr, "where options are:\n");
  233.     fprintf(stderr,
  234.         " -contig\tpack samples contiguously (e.g. RGBRGB...)\n");
  235.     fprintf(stderr,
  236.         " -separate\tstore samples separately (e.g. RRR...GGG...BBB...)\n");
  237.     fprintf(stderr, "\n");
  238.     fprintf(stderr,
  239.         " -lzw\t\tcompress output with Lempel-Ziv & Welch encoding\n");
  240.     fprintf(stderr,
  241.         " -packbits\tcompress output with packbits encoding\n");
  242.     fprintf(stderr,
  243.         " -none\t\tuse no compression algorithm on output\n");
  244.     fprintf(stderr, "\n");
  245.     fprintf(stderr,
  246.         " -8bit\tassume 8-bit colormap values (instead of 16-bit)\n");
  247.     fprintf(stderr,
  248.         " -rowsperstrip #\tmake each strip have no more than # rows\n");
  249.     exit(-1);
  250. }
  251.